# -*- coding: utf-8 -*-

#   This file is part of emesene.
#
#    Emesene is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    emesene is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with emesene; if not, write to the Free Software
#    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

import gtk
import os
import re
import shutil
import urllib

import paths
import Plugin

GoogleSvnPluginNames = re.compile('<a href="([^"]+)">') #thanks mohrtutchy and iElectric
GoogleSvnRevision = re.compile('<h2>Revision ([^"]+):')

PLUGIN_NAME, PLUGIN_DESC, PLUGIN_INST = (0, 1, 2)

class GoogleSvnPluginHandler:
    def __init__(self):
        pass
    def _get_current_trunk(self):
        print "get current"
        newsock = urllib.urlopen('http://emesene-plugins.googlecode.com/svn/trunk/') 
        rawhtml = newsock.read() 
        newsock.close()
        SvnPluginsList = GoogleSvnPluginNames.findall(rawhtml)
	# pop the 1st "../" and the latest two, which are useless to us ;)
        SvnPluginsList.pop(0)
        SvnPluginsList.pop()
        SvnPluginsList.pop()
        SvnRevision = GoogleSvnRevision.findall(rawhtml)
        
        return SvnRevision[0], SvnPluginsList
    
    def _get_plugin_from_svn(self, PluginName):
        print "get a nice plugin"
        fname, headers = urllib.urlretrieve('http://emesene-plugins.googlecode.com/svn/trunk/' + PluginName)
        return fname

class MainClass(Plugin.Plugin):

    def __init__(self, controller, msn):
        Plugin.Plugin.__init__(self, controller, msn)

        self.description = _('emesene plugin downloader')
        self.authors = {'C10uD': 'c10ud.dev@gmail.com'}
        self.website = 'http://emesene.org'
        self.displayName = _('Plugin Downloader')
        self.name = 'aaPluginDownloader'
        self.enabled = False
        
        self.config = controller.config
        self.controller = controller
        self.LocalPluginsPath = paths.PLUGIN_HOME_PATH + '/'
        self.autoupdate = 0
        

    def start(self):
        self.enabled = True

        self.svn = GoogleSvnPluginHandler()
        self.config.readPluginConfig( self.name )
        self.autoupdate = int(self.config.getPluginValue( self.name, 'AutoUpdateInstalledPlugins', '0' ) )
        self.LocalLastRevision = int(self.config.getPluginValue( self.name, 'LastRev', '0' ) )
        self.LocalPluginsInstalled = self.config.getPluginValue( self.name, 'Installed', 'aaPluginDownloader.py,' )
        
        if self.autoupdate == 1:
            self.update_installed_plugins()

    def replace_plugin( self, pluginname ):
        fn = self.svn._get_plugin_from_svn( pluginname )
        try:
            shutil.copy( fn, self.LocalPluginsPath + pluginname )
        except:
            raise IOError
   
    def phisically_remove_plugin( self, pluginname ):
        print 'removing ' + self.LocalPluginsPath + pluginname
        try:
            os.remove( self.LocalPluginsPath + pluginname )
        except:
            raise IOError

    def update_installed_plugins( self ):
        rev, pgs = self.svn._get_current_trunk()
        if rev > self.LocalLastRevision:
            for i in range( len( pgs ) ):
                if re.search( pgs[i], self.LocalPluginsInstalled ):
                    self.replace_plugin( pgs[i] )
            self.LocalLastRevision = rev
            self.config.setPluginValue( self.name, 'LastRev', self.LocalLastRevision )

    def stop(self):
        self.enabled = False

    def check(self):
        return (True, 'Ok')
 
    def configure( self ):
        if not self.enabled:
            return

        self.confWin = Plugin.ConfigWindow(_('emesene plugin downloader config'), '')

        cfgTable = gtk.Table(2)
        cfgTable.set_border_width(15)
        self._row = 0

        def addrow(text, cfgButton):
            row = self._row
            cfgLabel = gtk.Label(text)
            cfgLabel.set_alignment(0, 1)
            cfgTable.attach(cfgLabel, 0, 1, row, row + 1)
            cfgTable.attach(cfgButton, 1, 2, row, row + 1)
            self._row += 1

        #check for updates now
        chkAutoUpd = gtk.CheckButton()
        chkAutoUpd.set_active( self.autoupdate )
        addrow(_('Auto update installed plugins'), chkAutoUpd)

        # when clicking, check if localrev < svnrev then update selected
        btnUpd = gtk.Button(_('7up'))
        addrow(_('Update selected'), btnUpd)
        
        #Make a cool frame
        frame = gtk.Frame("Options")
        frame.set_border_width(5)
        frame.add(cfgTable)
        
        # on click update the treeview with eventually new svn plugins, with all available 
        # plugins in form of a checkable list..don't forget to check automagically the already installed ones
        rev, pgs = self.svn._get_current_trunk()

        lstSvnPlugins = gtk.ListStore (str, str, bool)
        
        iterx = lstSvnPlugins.get_iter_first()
        for i in range( len( pgs ) ):
            if re.search( pgs[i], self.LocalPluginsInstalled ):
                present = True
            else:
                present = False
            iterx = lstSvnPlugins.append( [pgs[i], '', present] )
            iterx = lstSvnPlugins.iter_next(iterx)

        svnview = gtk.TreeView(lstSvnPlugins)
        sel = svnview.get_selection()
        sel.set_mode( gtk.SELECTION_MULTIPLE )

        txcell = gtk.CellRendererText()
        column1 = gtk.TreeViewColumn( _('Nome'), txcell, text = PLUGIN_NAME )
        svnview.append_column( column1 )

        dscell = gtk.CellRendererText()
        column2 = gtk.TreeViewColumn( _('Desc'), dscell, text = PLUGIN_DESC )
        svnview.append_column( column2 )

        def ck_toggled( cell, path, lstSvnPlugins ):
            ''' i hate you damn callbacks ;_; '''
            qiter = lstSvnPlugins.get_iter( path )
            active = lstSvnPlugins.get_value( qiter, PLUGIN_INST )
            lstSvnPlugins.set_value( qiter, PLUGIN_INST, not active )
        
        ckcell = gtk.CellRendererToggle()
        ckcell.set_property( 'activatable', True )
        ckcell.connect( 'toggled', ck_toggled, lstSvnPlugins )
        column3 = gtk.TreeViewColumn( _('Installed'), ckcell, active = PLUGIN_INST )
        svnview.append_column( column3 )
        
        #Let's make treeview Scrollable
        scrollwindow = gtk.ScrolledWindow()
        scrollwindow.set_size_request( 300, 300 )
        scrollwindow.add(svnview)

        def get_selected_plugins():
            selected = ''
            xiter = lstSvnPlugins.get_iter_first()
            while xiter:
                activ = lstSvnPlugins.get_value (xiter, PLUGIN_INST)
                if activ:
                    selected += lstSvnPlugins.get_value(xiter,PLUGIN_NAME) + ','
                xiter=lstSvnPlugins.iter_next(xiter)
            return selected
        
        def remove_not_selected ( PlainList ):
        # remove previously installed plugins that aren't selected anymore
            pgList = re.split( ',+', self.LocalPluginsInstalled )
            for x in range( len( pgList ) ):
                if pgList[x] != '' and not re.search( pgList[x], PlainList ):
                    self.phisically_remove_plugin( pgList[x] )

        def update_pressed( button ):
            sel1 = get_selected_plugins()
            self.LocalPluginsInstalled = sel1
            self.config.setPluginValue( self.name, 'Installed', self.LocalPluginsInstalled )
            self.update_installed_plugins()

        btnUpd.connect( 'released', update_pressed )

        self.confWin.vbox.pack_start( scrollwindow, True, True, 5)
        self.confWin.vbox.pack_start( frame )
        self.confWin.show_all()

        r = self.confWin.run()
        
        if r is not None:
            self.config.setPluginValue( self.name, 'AutoUpdateInstalledPlugins', int( chkAutoUpd.get_active() ) )
                        
            sel = get_selected_plugins()
            remove_not_selected( sel )
            self.LocalPluginsInstalled = sel
            self.update_installed_plugins()
            self.config.setPluginValue( self.name, 'Installed', self.LocalPluginsInstalled )
            
            #[quote] YES YOU'VE GUESSED RIGHT! THIS IS A HACK! [/quote]
            self.stop()
            self.start()

        return True

